package com.dkm.orproject.dkmoa.service.serviceimpl.flow;

import com.dkm.orproject.dkmoa.dao.*;
import com.dkm.orproject.dkmoa.domain.*;
import com.dkm.orproject.dkmoa.service.flow.OaDimissionFlowService;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName : OaDimissionFlowServiceImpl  //类名
 * @Description : 员工离职服务实现类  //描述
 * @Author : 易嵘  //作者
 * @Date: 2020-08-14 10:44  //时间
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OaDimissionFlowServiceImpl implements OaDimissionFlowService {

    /**
     * 员工离职dao
     */
    @Resource
    OaDimissionFlowMapper dimissionFlowMapper;

    /**
     * 流程记录日志
     */
    @Resource
    OaFlowScheduleMapper flowScheduleMapper;

    /**
     * 人员Mapper
     */
    @Resource
    OaPersonnelMapper personnelMapper;

    /**
     * 通知Mapper
     */
    @Resource
    OaMessageMapper messageMapper;

    /**
     * 通知人员关联Mapper
     */
    @Resource
    OaInformMapper informMapper;

    /**
     * 流程Mapper
     */
    @Resource
    OaFlowMapper flowMapper;

    /**
     * 部门Mapper
     */
    @Resource
    OaDepartmentMapper departmentMapper;


    /**
     * id工具类
     */
    @Resource
    IdToobtainUtils idToobtainUtils;

    /**
     * 开始节点id
     */
    static final Long START_NODE = 753573705115906048L;

    /**
     * 部门审核节点id
     */
    static final Long AUDIT_SECTION_NODE = 753578931113832448L;

    /**
     * 人事审核节点id
     */
    static final Long AUDIT_STAFFING_NODE = 753579155077083136L;

    /**
     * 结束节点id
     */
    static final Long OVER_NODE = 753615793052332032L;

    /**
     * 人事审核通知
     */
    static final String STAFFING_CHECK_INFORM="STAFFING_CHECK_INFORM";

    /**
     * 起草新增
     *
     * @param dimissionFlow 离职流程模型
     * @param personnel     操作人
     * @return 回调函数
     */
    @Override
    public int add(OaDimissionFlow dimissionFlow, OaPersonnel personnel) {
        // 创建人名称
        dimissionFlow.setCreatedBy(personnel.getPersonnelName());
        //离职名称
        dimissionFlow.setDemissionName(personnel.getPersonnelName() + "的离职流程");
        // D为部门审核
        dimissionFlow.setIsRevision("D");
        // 进度设置为部门领导审核
        dimissionFlow.setDimissionSchedule(AUDIT_SECTION_NODE);


        if (dimissionFlow.getPkDimissionId() == null) {
            // 离职流程id
            dimissionFlow.setPkDimissionId(idToobtainUtils.getNumberId());
            // 流程记录
            OaFlowSchedule flowSchedule = new OaFlowSchedule();
            // 流程记录id
            flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
            // 离职流程id  起草节点
            flowSchedule.setFlowId(START_NODE);
            // 绑定表单
            flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
            // 人员id
            flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
            // 通过原因
            flowSchedule.setFormReason("  ");
            //审核人
            flowSchedule.setCreatedBy(personnel.getPersonnelName());
            // 新增离职流程记录
            flowScheduleMapper.insertSelective(flowSchedule);
            //通知部门领导
            //删除旧通知
            messageMapper.deleteByFormId(dimissionFlow.getPkDimissionId());

            // 新建通知
            OaMessage message = new OaMessage();
            //通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            //创建人
            message.setCreatedBy(personnel.getPersonnelName());
            //流程id
            message.setFormId(dimissionFlow.getPkDimissionId());
            // 通知标题
            message.setMessageName(dimissionFlow.getDemissionName());
            //状态 2 待办
            message.setIsRevision("2");
            // 链接地址
            message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionAudit.html?pkDimissionId=");
            // 新增通知
            messageMapper.insertSelective(message);

            //查询部门领导
            Long personnelId = departmentMapper.selectByPrimaryKey(personnel.getPkDepartmentId()).getPersonnelId();

            // 新建通知关联
            OaInform inform = new OaInform();
            // 通知关联id
            inform.setFkInformId(idToobtainUtils.getNumberId());
            // 设置为未读
            inform.setIsState("0");
            // 通知id
            inform.setMessageId(message.getPkMessageId());
            // 人员id
            inform.setPersonnelId(personnelId);

            informMapper.insertSelective(inform);
            return dimissionFlowMapper.insertSelective(dimissionFlow);
        } else {
            // 流程记录
            OaFlowSchedule flowSchedule = new OaFlowSchedule();
            // 流程记录id
            flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
            // 离职流程id  起草节点
            flowSchedule.setFlowId(START_NODE);
            // 绑定表单
            flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
            // 人员id
            flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
            // 通过原因
            flowSchedule.setFormReason("  ");
            //审核人
            flowSchedule.setCreatedBy(personnel.getPersonnelName());
            // 新增离职流程记录
            flowScheduleMapper.insertSelective(flowSchedule);
            //通知部门领导
            //删除旧通知
            messageMapper.deleteByFormId(dimissionFlow.getPkDimissionId());

            // 新建通知
            OaMessage message = new OaMessage();
            //通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            //创建人
            message.setCreatedBy(personnel.getPersonnelName());
            //流程id
            message.setFormId(dimissionFlow.getPkDimissionId());
            // 通知标题
            message.setMessageName(dimissionFlow.getDemissionName());
            //状态 2 待办
            message.setIsRevision("2");
            // 链接地址
            message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionAudit.html?pkDimissionId=");
            // 新增通知
            messageMapper.insertSelective(message);
            //查询部门领导
            Long personnelId = departmentMapper.selectByPrimaryKey(personnel.getPkDepartmentId()).getPersonnelId();
            // 新建通知关联
            OaInform inform = new OaInform();
            // 通知关联id
            inform.setFkInformId(idToobtainUtils.getNumberId());
            // 设置为未读
            inform.setIsState("0");
            // 通知id
            inform.setMessageId(message.getPkMessageId());
            // 人员id
            inform.setPersonnelId(personnelId);

            informMapper.insertSelective(inform);

            return dimissionFlowMapper.updateByPrimaryKeySelective(dimissionFlow);
        }
    }

    /**
     * 部门领导同意
     *
     * @param pkDimissionId        离职流程模型
     * @param personnel            操作人
     * @param departmentLeadership 部门领导意见
     * @return 回调函数
     */
    @Override
    public int sectionPass(Long pkDimissionId, OaPersonnel personnel, String departmentLeadership) {

        OaDimissionFlow dimissionFlow = dimissionFlowMapper.selectByPrimaryKey(pkDimissionId);
        // S为人事审核
        dimissionFlow.setIsRevision("S");
        // 进度设置为人事审核
        dimissionFlow.setDimissionSchedule(AUDIT_STAFFING_NODE);
        // 部门领导意见
        dimissionFlow.setDepartmentLeadership(departmentLeadership);
        //审核时间
        dimissionFlow.setLeadershipContentTime(new Date());
        //审核人
        dimissionFlow.setUpdatedBy(personnel.getPersonnelName());

        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  部门领导审核节点
        flowSchedule.setFlowId(AUDIT_SECTION_NODE);
        // 绑定表单
        flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);


        //删除旧通知
        messageMapper.deleteByFormId(dimissionFlow.getPkDimissionId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(dimissionFlow.getPkDimissionId());
        // 通知标题
        message.setMessageName(dimissionFlow.getDemissionName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionAudit.html?pkDimissionId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 根据通知权限代码查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(STAFFING_CHECK_INFORM);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }


        return dimissionFlowMapper.updateByPrimaryKeySelective(dimissionFlow);
    }

    /**
     * 部门领导不同意
     *
     * @param pkDimissionId 离职流程模型
     * @param personnel     操作人
     * @param formReason    部门领导意见
     * @return 回调函数
     */
    @Override
    public int sectionNoPass(Long pkDimissionId, OaPersonnel personnel, String formReason) {
        OaDimissionFlow dimissionFlow = dimissionFlowMapper.selectByPrimaryKey(pkDimissionId);
        // C为起草节点
        dimissionFlow.setIsRevision("C");
        // 进度设置为人事审核
        dimissionFlow.setDimissionSchedule(START_NODE);
        //审核人
        dimissionFlow.setUpdatedBy(personnel.getPersonnelName());
        // 部门领导意见
        dimissionFlow.setDepartmentLeadership("");

        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  部门领导审核节点
        flowSchedule.setFlowId(AUDIT_SECTION_NODE);
        // 绑定表单
        flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(pkDimissionId);
        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(pkDimissionId);
        // 通知标题
        message.setMessageName(dimissionFlow.getDemissionName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionFrom.html?pkDimissionId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(dimissionFlow.getPersonnelId());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);

        return dimissionFlowMapper.updateByPrimaryKeySelective(dimissionFlow);
    }

    /**
     * 人事部同意
     *
     * @param pkDimissionId 离职流程模型
     * @param personnel     操作人
     * @param formReason    人事意见
     * @return 回调函数
     */
    @Override
    public int staffingPass(Long pkDimissionId, OaPersonnel personnel, String formReason) {
        OaDimissionFlow dimissionFlow = dimissionFlowMapper.selectByPrimaryKey(pkDimissionId);
        // 1流程结束
        dimissionFlow.setIsRevision("1");
        // 进度设置为 结束节点
        dimissionFlow.setDimissionSchedule(OVER_NODE);
        //审核人
        dimissionFlow.setUpdatedBy(personnel.getPersonnelName());
        // 审核时间
        dimissionFlow.setDepartmentLeadershipTime(new Date());
        // 人事意见
        dimissionFlow.setPersonnelCondition(formReason);
        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  人事审核节点
        flowSchedule.setFlowId(AUDIT_STAFFING_NODE);
        // 绑定表单
        flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //流程记录
        OaFlowSchedule flowSchedule1 = new OaFlowSchedule();
        // 流程记录id
        flowSchedule1.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  人事审核节点
        flowSchedule1.setFlowId(OVER_NODE);
        // 绑定表单
        flowSchedule1.setFormId(dimissionFlow.getPkDimissionId());
        // 人员id
        flowSchedule1.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原
        flowSchedule1.setFormReason("  ");
        //审核人
        flowSchedule1.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule1);
        //日期到达时将人员设置为无效
        //Tools.timing(dimissionFlow.getDimissionTime());
        //通知交接人填表
        //删除旧通知
        messageMapper.deleteByFormId(pkDimissionId);
        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(pkDimissionId);
        // 通知标题
        message.setMessageName(dimissionFlow.getDemissionName());
        //状态 4 已办
        message.setIsRevision("4");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionAudit.html?show=1&pkDimissionId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id 通知起草人
        inform.setPersonnelId(dimissionFlow.getPersonnelId());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);

        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(pkDimissionId);
        // 通知标题
        message.setMessageName(dimissionFlow.getDemissionName() + " 待交接");
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/dimissionHover/dimissionHoverAdd.html?pkDimissionId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id 通知交接人
        inform.setPersonnelId(dimissionFlow.getPersonnelIds());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);

        return dimissionFlowMapper.updateByPrimaryKeySelective(dimissionFlow);
    }

    /**
     * 人事部不同意
     *
     * @param pkDimissionId 离职流程模型
     * @param personnel     操作人
     * @param formReason    审核意见
     * @return 回调函数
     */
    @Override
    public int staffingNoPass(Long pkDimissionId, OaPersonnel personnel, String formReason) {
        OaDimissionFlow dimissionFlow = dimissionFlowMapper.selectByPrimaryKey(pkDimissionId);
        // C为起草节点
        dimissionFlow.setIsRevision("C");
        // 进度设置为起草节点
        dimissionFlow.setDimissionSchedule(START_NODE);
        // 清空部门领导意见
        dimissionFlow.setDepartmentLeadership("");
        // 清空人事意见
        dimissionFlow.setPersonnelCondition("");
        //审核人
        dimissionFlow.setUpdatedBy(personnel.getPersonnelName());
        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  人事审核节点
        flowSchedule.setFlowId(AUDIT_STAFFING_NODE);
        // 绑定表单
        flowSchedule.setFormId(dimissionFlow.getPkDimissionId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        //删除旧通知
        messageMapper.deleteByFormId(pkDimissionId);
        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(pkDimissionId);
        // 通知标题
        message.setMessageName(dimissionFlow.getDemissionName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/dimission/dimissionFrom.html?pkDimissionId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(dimissionFlow.getPersonnelId());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);
        return dimissionFlowMapper.updateByPrimaryKeySelective(dimissionFlow);
    }

    /**
     * id删除
     *
     * @param id
     * @return
     */
    @Override
    public int delete(Long id) {
        flowScheduleMapper.deleteByPrimaryKey(id);
        return dimissionFlowMapper.deleteByPrimaryKey(id);
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public int deleteAll(List<Long> ids) {
        flowScheduleMapper.deleteAll(ids);
        return dimissionFlowMapper.deleteAll(ids);
    }

    /**
     * 分页查询
     *
     * @param dimissionFlow
     * @param page
     * @param limit
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<OaDimissionFlow> findAll(OaDimissionFlow dimissionFlow, Integer page, Integer limit, String startDate, String endDate) {
        PageHelper.startPage(page, limit);
        return dimissionFlowMapper.findAll(dimissionFlow, startDate, endDate);
    }

    /**
     * 总行数
     *
     * @param dimissionFlow
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public Long rowCount(OaDimissionFlow dimissionFlow, String startDate, String endDate) {
        return dimissionFlowMapper.rowCount(dimissionFlow, startDate, endDate);
    }

    /**
     * id查询
     *
     * @param id
     * @return
     */
    @Override
    public OaDimissionFlow findById(Long id) {
        return dimissionFlowMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询是否已提交离职申请
     *
     * @param pkPersonnelId
     * @return
     */
    @Override
    public int getDimissionFlow(Long pkPersonnelId) {
        return dimissionFlowMapper.getDimissionFlow(pkPersonnelId);
    }
}
